package com.springboot.demo.common.interceptor;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义Base拦截器
 * Created by Ranj on 2017/9/11 0011.
 */
public abstract class BaseInterceptor extends HandlerInterceptorAdapter {

    public String failed;

    public String name;

    /**
     * 自定义拦截逻辑
     *
     * @param handler
     * @return 是否拦截, false拦截, true:不拦截;
     */
    public boolean isMyHandler(Object handler) {
        // 判断是否应该被拦截
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Interceptor interceptor = handlerMethod.getMethodAnnotation(Interceptor.class);
        // 只有被@Interceptor注解的类才会被拦截
        if (interceptor == null) {
            return true;
        }
        failed = interceptor.failed();
        name = interceptor.name();

        return false;
    }

    /**
     * 重写preHandle方法
     */
    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {
        if (!isMyHandler(handler)) {
            return doHandler(response, runHandler(request, response));
        }
        return super.preHandle(request, response, handler);
    }

    public abstract boolean runHandler(HttpServletRequest request, HttpServletResponse response);

    /**
     * 根据运行结果做相应的处理
     *
     * @param response
     * @param isInterceptor 是否拦截,false拦截,true:不拦截;
     * @return 是否拦截, false拦截, true:不拦截;
     * @throws Exception
     */
    public boolean doHandler(HttpServletResponse response, boolean isInterceptor) throws Exception {
        if (!isInterceptor) {
            if (!failed.equals("")) {
                // to do something
            }
            return false;
        }
        return true;
    }

    /**
     * 自定义拦截器配套注解
     *
     * @author Oliver
     * @version 20161214
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface Interceptor {

        // 根据业务需求确定用途，也可省略,例如log打印，方法判定等
        public String name();

        // 根据业务需求确定用途，也可省略，例如指定失败跳转，或者失败后to do something
        public String failed() default "";
    }
}
